package com.otherTest.designpattern.creationalpattern.singleton;


import com.otherTest.designpattern.creationalpattern.singleton.checkin.SingleCheckInBaseObject;
import com.otherTest.designpattern.creationalpattern.singleton.dcl.SingleDoubleCheckLockBaseObject;
import com.otherTest.designpattern.creationalpattern.singleton.enums.SingleBaseObjectEnum;
import com.otherTest.designpattern.creationalpattern.singleton.hungry.SingleHungryBaseObject;
import com.otherTest.designpattern.creationalpattern.singleton.lazy.SingleLazyThreadSafeBaseObject;
import com.otherTest.designpattern.creationalpattern.singleton.lazy.SingleLazyThreadUnsafeBaseObject;

/**
 * @Description: 单例模式
 * <p>
 * 单例模式可以保证在系统中，该对象只有一个实例存在，并提供一个全局访问点。
 * 关键代码：构造函数是私有的。
 * 注意事项：getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
 * <p>
 * 优点：
 * 1.节省性能开销
 * 2.避免资源的多重占用
 * <p>
 * 缺点：
 * 1.没有接口
 * 2.不能继承
 * 3.与单一职责原则冲突，一个类只应该关注内心逻辑，而不关心外部怎么实例化
 * @author: conceit
 * @Date: 2018/8/28 20:53
 */
public class SingleMainTest {


    /**
     * @Description: 单例模式测试方法
     * @author: conceit
     * @Date: 2018/8/29  10:40
     */
    public static void main(String[] args) {

        //懒汉式-非线程安全
        SingleLazyThreadSafeBaseObject singleLazyThreadSafeBaseObject = SingleLazyThreadSafeBaseObject.getInstance();
        singleLazyThreadSafeBaseObject.showMessage();

        //懒汉式-线程安全
        SingleLazyThreadUnsafeBaseObject singleLazyThreadUnsafeBaseObject = SingleLazyThreadUnsafeBaseObject.getInstance();
        singleLazyThreadUnsafeBaseObject.showMessage();

        //饿汉式
        SingleHungryBaseObject singleHungryBaseObject = SingleHungryBaseObject.getInstance();
        singleHungryBaseObject.showMessage();

        //双重锁
        SingleDoubleCheckLockBaseObject singleDoubleCheckLockBaseObject = SingleDoubleCheckLockBaseObject.getInstance();
        //选择两个实例分别打印内存中的地址
        System.out.println(singleDoubleCheckLockBaseObject);
        System.out.println(SingleDoubleCheckLockBaseObject.getInstance());
        singleDoubleCheckLockBaseObject.showMessage();

        //登记式
        SingleCheckInBaseObject singleCheckInBaseObject = SingleCheckInBaseObject.getInstance();
        System.out.println(SingleCheckInBaseObject.getInstance());
        System.out.println(SingleCheckInBaseObject.getInstance());
        singleCheckInBaseObject.showMessage();

        //枚举式
        SingleBaseObjectEnum singleBaseObjectEnum = SingleBaseObjectEnum.INSTANCE;
        System.out.println(SingleBaseObjectEnum.INSTANCE.hashCode());
        System.out.println(SingleBaseObjectEnum.INSTANCE.hashCode());
        singleBaseObjectEnum.showMessage();

    }


}
